/*MyPhotoIndex Free Photo Organizer <www.myphotoindex.com>
  Copyright (C) <2006-2009>  <Asaf Yarkoni asaf@yarkoni.net>

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using MyPhotoIndex.Controls;
using MyPhotoIndex.Properties;
using System.Collections.Specialized;
using MyPhotoIndex.Importer;
using MyPhotoIndex.DataAccess;
using MyPhotoIndex.ImageBank.Query;
using MyPhotoIndex.ImageBank;
using MyPhotoIndex.Utilities;
using MyPhotoIndex.Plugins.ImageFormatProviders;
using MyPhotoIndex.Plugins.DataProviders;
using MyPhotoIndex.Interfaces.FileSearch;
using MyPhotoIndex.Utilities.FileSearch;
using MyPhotoIndex.Interfaces.Tagging;
using MyPhotoIndex.Settings;

namespace MyPhotoIndex.Wizards.Import
{
    public partial class ImageFilesImportWizard : WizardHost
    {
        delegate void UpdateImportStatusDelegate(ImageDataImporterEventArgs e);

        private const int WizardPage_Welcome = 0;
        private const int WizardPage_AddFiles = 1;
        private const int WizardPage_ViewImages = 2;
        private const int WizardPage_AddImageTags = 3;
        private const int WizardPage_Import = 4;
        private const int WizardPage_Finish = 5;

        private StringCollection        m_allFiles;
        private FileImageDataImporter   m_importer;
        private String                  m_importBatchId;
        private ImageFileCollection     m_imageCollection;

        private bool                    m_useOneTag;
        private IImageTag               m_tagsExistingTag;
        private string                  m_tagsNewTagName;
        private bool                    m_stop;
        private bool                    m_isImporterRunning;

        public ImageFilesImportWizard()
        {
            InitializeComponent();
            myPhotoIndexThumbnailViewer1.Buffered = false;

            base.PageNumberChangedEvent += new EventHandler<PageNumberChangedEventArgs>(ImageFilesImportWizard_PageNumberChengedEvent);
            base.WizardFinishedEvent += new EventHandler(ImageFilesImportWizard_WizardFinishedEvent);
            base.SetPageNextButtonText(WizardPage_AddImageTags, Resources.Resources.FileImportWizard_Import);

            dontHelpRadioButton.CheckedChanged += new EventHandler(RadioButton_CheckedChanged);
            autoGenerateTagsRadioButton.CheckedChanged += new EventHandler(RadioButton_CheckedChanged);
            tagAllImagesRadioButton.CheckedChanged += new EventHandler(RadioButton_CheckedChanged);
            newTagNameRadioButton.CheckedChanged += new EventHandler(RadioButton_CheckedChanged);
            existingTagRadioButton.CheckedChanged += new EventHandler(RadioButton_CheckedChanged);

            m_importBatchId = Guid.NewGuid().ToString();
            importProgressLabel.Text = string.Empty;

            if (Storage.Instance.UnFiltered.Count == 0)
            {
                rbtSearchComputer.Checked = true;
            }
            else
            {
                rbtSerachFolders.Checked = true;
            }

            UpdateTagCreationButtonsStatus();
        }

        void ImageFilesImportWizard_PageNumberChengedEvent(object sender, PageNumberChangedEventArgs e)
        {
            if (e.PageNumber == WizardPage_ViewImages &&
                e.PageNumberBefore == WizardPage_AddFiles)
            {
                FilesSearch filesSearch = new FilesSearch();
                filesSearch.SearchPattern = ImageFormatProviders.Default.ImporterFilterFormat;
                filesSearch.SearchSubfolders = cbSearchSubFolders.Checked;
                filesSearch.IgnoreSystemFolders = cbIgnoreSystemDirs.Checked;

                this.Cursor = Cursors.WaitCursor;

                if (rbtSearchComputer.Checked == true)
                {
                    filesSearch.SearchLocations.Add(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
                }
                else
                    if (rbtSerachFolders.Checked == true)
                    {
                        foreach (String serachDir in listBox1.Items)
                        {
                            filesSearch.SearchLocations.Add(serachDir);
                        }
                    }

                if (ignoresmallFilesCheckBox.Checked == true)
                {
                    List<IFileSearchFilter> filter = new List<IFileSearchFilter>();
                    filter.Add(new FileSizeFileSearchFilter(30));
                    filesSearch.Filter = filter.AsReadOnly();
                }

                filesSearch.FilesSearchEvent += new EventHandler<FileSearchEventAgs>(filesSerch_FilesSearchEvent);

                myPhotoIndexThumbnailViewer1.SingleSelection = true;
                myPhotoIndexThumbnailViewer1.Buffered = true;
                myPhotoIndexThumbnailViewer1.ImageList = null;
                myPhotoIndexThumbnailViewer1.Refresh();
                FilesSearchForm fileSearchForm = new FilesSearchForm(filesSearch);
                fileSearchForm.ShowDialog(this);
                m_allFiles = new StringCollection();

                String[] fileArray = new String[filesSearch.FileList.Count];
                filesSearch.FileList.CopyTo(fileArray, 0);
                m_allFiles.AddRange(fileArray);
                if (m_imageCollection != null)
                {
                    m_imageCollection.Dispose();
                }

                m_imageCollection = new ImageFileCollection(fileArray);
                myPhotoIndexThumbnailViewer1.ImageList = m_imageCollection;
                myPhotoIndexThumbnailViewer1.Buffered = true;
                myPhotoIndexThumbnailViewer1.ScrollbarVisible = true;

                this.Cursor = Cursors.Arrow;

                imageCountLabel.Text = string.Format(Resources.Resources.FileImportImagesFound, m_imageCollection.Count);

                myPhotoIndexThumbnailViewer1.CheckAll();
            }

            if (e.PageNumber == WizardPage_AddImageTags &&
                e.PageNumberBefore == WizardPage_ViewImages)
            {
                BuildExistingTagsList();
            }

            if (e.PageNumber == WizardPage_Import &&
                e.PageNumberBefore == WizardPage_AddImageTags)
            {
                foreach (int checkedId in myPhotoIndexThumbnailViewer1.UncheckedImages)
                {
                    m_allFiles.Remove(myPhotoIndexThumbnailViewer1.ImageList[checkedId].FileName);
                }

                DisableButtons();
                CloseButton.Enabled = true;

                #region tags creatation settings
                if (tagAllImagesRadioButton.Checked == true)
                {
                    m_useOneTag = true;
                    if (newTagNameRadioButton.Checked == true)
                    {
                        m_tagsNewTagName = newTagNameTextBox.Text.Trim();
                    }
                    else
                        if (existingTagRadioButton.Checked == true)
                        {
                            m_tagsExistingTag = ((ExistingTagListItem)existingTagsComboBox.SelectedItem).Tag;
                        }
                }
                else
                {
                    m_useOneTag = false;
                }
                #endregion

                importedFileNameLabel.Text = String.Empty;
                this.Cursor = Cursors.WaitCursor;

                String[] fileArray = new String[m_allFiles.Count];
                m_allFiles.CopyTo(fileArray, 0);
                progressBar1.Maximum = m_allFiles.Count;

                m_importer = new FileImageDataImporter(m_importBatchId);
                m_importer.UseCentralStorage = ApplicationFolders.UseCentralStorage;
                m_importer.CentralStoragePath = ApplicationFolders.CentralStorageLocation;

                m_importer.SetImageTagsEvent += new EventHandler<SetImageTagsEventArgs>(m_importer_SetImageTagsEvent);
                m_importer.ImageDataImporterProcessEvent += new EventHandler<ImageDataImporterEventArgs>(importer_ImageDataImporterProcessEvent);

                BackgroundWorker bw = new BackgroundWorker();
                bw.DoWork += new DoWorkEventHandler(bw_DoWork);
                bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
                bw.RunWorkerAsync(fileArray);

                m_isImporterRunning = true;
            }

            if (e.PageNumber == WizardPage_Finish &&
                e.PageNumberBefore == WizardPage_Import)
            {
                if (m_importer.Errors.Count > 0)
                {
                    foreach (ImageImportException ex in m_importer.Errors)
                    {
                        listBox2.Items.Add(ex.FileName);
                    }
                }
                else
                {
                    label9.Visible = false;
                    listBox2.Visible = false;
                }
            }
        }

        void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            m_isImporterRunning = false;
            this.Cursor = Cursors.Arrow;
            EnableButtons();

            NextButtonClick(this, EventArgs.Empty);
        }

        void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            String[] fileArray = e.Argument as String[];
            m_importer.ImportFromFileList(fileArray, ApplicationSettings.Default.CachedThumbnailSize);
        }

        void filesSerch_FilesSearchEvent(object sender, FileSearchEventAgs e)
        {
            imageCountLabel.Text = string.Format(Resources.Resources.FileImportImagesFound, e.FilesFound);
        }

        void importer_ImageDataImporterProcessEvent(object sender, ImageDataImporterEventArgs e)
        {
            this.Invoke(new UpdateImportStatusDelegate(UpdateImportStatus), new Object[] { e });
        }

        private void UpdateImportStatus(ImageDataImporterEventArgs e)
        {
            ImageDataImporterEventArgs importstatus = e;

            //importing file xxx
            importedFileNameLabel.Text = String.Format(Resources.Resources.FileImportWizard_ImportingMessage, importstatus.CurrentFile);
            importedFileNameLabel.Refresh();
            importProgressLabel.Text = string.Format("{0}/{1}", e.FileOffset, m_imageCollection.Count);
            if (pictureBox1.Image != null)
            {
                pictureBox1.Image.Dispose();
                pictureBox1.Image = null;
            }

            if (importstatus.Thumbnail != null)
            {
                pictureBox1.Image = new Bitmap(importstatus.Thumbnail);
                pictureBox1.Refresh();
            }

            progressBar1.Value = importstatus.FileOffset;

            if (m_stop == true)
            {
                e.Stop = true;
            }

            Application.DoEvents();
        }

        private void AddBtn_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.RootFolder = Environment.SpecialFolder.Desktop;
            if (string.IsNullOrEmpty(ApplicationSettings.Default.LastImportPath) == true)
            {
                folderBrowserDialog1.SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
            }
            else
            {
                folderBrowserDialog1.SelectedPath = ApplicationSettings.Default.LastImportPath;
            }

            DialogResult dr = folderBrowserDialog1.ShowDialog();
            if (dr == DialogResult.OK)
            {
                listBox1.Items.Add(folderBrowserDialog1.SelectedPath);
                ApplicationSettings.Default.LastImportPath = folderBrowserDialog1.SelectedPath;
                ApplicationSettings.Default.Save();
            }
        }

        private void RemoveBtn_Click(object sender, EventArgs e)
        {
            if (listBox1.SelectedItem != null)
            {
                listBox1.Items.Remove(listBox1.SelectedItem);
            }
        }

        protected override void NextButtonClick(object sender, EventArgs e)
        {
            if (PageNumber == 0 &&
                rbtSearchComputer.Checked == true)
            {
                base.NextButtonClick(sender, e);
            }

            if (PageNumber == WizardPage_AddFiles)
            {
                if (rbtSerachFolders.Checked == true && 
                    listBox1.Items.Count == 0)
                {
                    ApplicationAlert.Show(Resources.Resources.FileImportWizard_MustSelect, Resources.Resources.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }
            }

            if (PageNumber == WizardPage_AddImageTags)
            {
                if (tagAllImagesRadioButton.Checked == true)
                {
                    if (newTagNameRadioButton.Checked == true)
                    {
                        if (string.IsNullOrEmpty(newTagNameTextBox.Text.Trim()) == true)
                        {
                            ApplicationAlert.Show(Resources.Resources.FileImportWizard_InvalidNewTagName, Resources.Resources.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                            return;
                        }
                    }
                    else
                    {
                        if (existingTagsComboBox.SelectedIndex == 0)
                        {
                            ApplicationAlert.Show(Resources.Resources.FileImportWizard_selectTag, Resources.Resources.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                            return;
                        }
                    }
                }
            }

            base.NextButtonClick(sender, e);
        }

        protected override void BackButtonClick(object sender, EventArgs e)
        {
            if (PageNumber == WizardPage_ViewImages &&
                rbtSearchComputer.Checked == true)
            {
                base.BackButtonClick(sender, e);
            }

            base.BackButtonClick(sender, e);
        }

        protected override void CancelButtonClick(object sender, EventArgs e)
        {
            if (m_importer != null && 
                m_isImporterRunning == true)
            {
                DialogResult dr = ApplicationAlert.Show(Resources.Resources.StopImportQuestion, Resources.Resources.FileImportWizard_Import, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (dr == DialogResult.Yes)
                {
                    m_stop = true;
                }

                return;
            }

            base.CancelButtonClick(sender, e);
        }

        void ImageFilesImportWizard_WizardFinishedEvent(object sender, EventArgs e)
        {
            ImageTagCollection.Instance.Load((ITagsDataAccessProvider)DataAccessProvider.Instance);

            QueryParameter[] queryParameters = new QueryParameter[] { new ImageBatchQueryParameter(m_importBatchId) };
            Storage.Instance.LoadImageList();
            Storage.Instance.Filter(queryParameters);
        }

        void RadioButton_CheckedChanged(object sender, EventArgs e)
        {
            UpdateTagCreationButtonsStatus();
        }

        private void UpdateTagCreationButtonsStatus()
        {
            if (tagAllImagesRadioButton.Checked == true)
            {
                newTagNameRadioButton.Enabled = true;
                existingTagRadioButton.Enabled = true;

                newTagNameTextBox.Enabled = (newTagNameRadioButton.Checked == true);
                existingTagsComboBox.Enabled = (existingTagRadioButton.Checked == true);
            }
            else
            {
                newTagNameRadioButton.Enabled = false;
                newTagNameTextBox.Enabled = false;
                existingTagRadioButton.Enabled = false;
                existingTagsComboBox.Enabled = false;
            }
        }

        private void BuildExistingTagsList()
        {
            existingTagsComboBox.Items.Clear();
            existingTagsComboBox.Items.Add(Resources.Resources.FileImportWizard_SelectTagCombo);
            existingTagsComboBox.SelectedIndex = 0;

            BuildExistingTagsList(0, ImageTagCollection.Instance.Tags);
        }

        private void BuildExistingTagsList(int level, List<IImageTag> tagList)
        {
            foreach (IImageTag tag in tagList)
            {
                existingTagsComboBox.Items.Add(new ExistingTagListItem(tag, level));

                BuildExistingTagsList(level + 1, tag.ChildTags);
            }
        }

        void m_importer_SetImageTagsEvent(object sender, SetImageTagsEventArgs e)
        {
            if (m_useOneTag == true)
            {
                if (m_tagsExistingTag == null)
                {
                    TaggingAssistant taggingAssistant = new TaggingAssistant(m_tagsNewTagName);
                    e.ImageTags.Add(taggingAssistant.Tag);
                }
                else
                {
                    e.ImageTags.Add(m_tagsExistingTag);
                }
            }
        }
    }   
}

